import { produce } from "immer";
import { create } from "zustand";

export interface ComponentNode {
  id?: number; // 组件id
  parentId?: number; // 父组件id
  name: string; //组件类型
  desc?: string; //组件描述
  props: Record<string, any>; // 组件属性
  events?: Record<string, any>; // 组件有什么事件
  bindEvents?: Array<Record<string, any>>; // 组件绑定的事件
  children?: ComponentNode[];
}
interface ComponenState {
  components: ComponentNode[]; //组件树
  currentElement: ComponentNode | null; //当前选中组件
  currentId: number | null; //当前选中组件id
  pageJs: Array<any>; //页面js代码
  editMode: boolean; // 编辑模式或预览模式
}
export type Position = "before" | "after"; // 插入位置

interface ComponentActions {
  addComponent: (component: ComponentNode, parentId: number) => void;
  removeComponent: (id: number) => void;
  setCurComponent: (id: number | null) => void; // 设置选中的组件
  updateComponent: (
    component: ComponentNode,
    id: number,
    position: Position
  ) => void;
  moveComponent: (id: number, targetId: number, position?: Position) => void;
  setCurComponentProps: (props: Record<string, any>) => void; // 设置选中组件的属性
  resetComponents: () => void;
  setPageJs: (js: Array<any>) => void; // 设置页面js代码
  addPageJs: (js: object) => void; // 添加页面js代码
  setBindEvents: (id: number, events: Record<string, any>) => void; // 设置组件绑定的事件
  setEditMode: (mode: boolean) => void; // 设置编辑模式或预览模式
}

const useComponentStore = create<ComponenState & ComponentActions>(
  (set, get) => ({
    components: [
      {
        id: 1,
        name: "Page",
        desc: "页面",
        events: {},
        bindEvents: [],
        props: {},
        children: [],
      },
    ],
    currentElement: null,
    currentId: null,
    pageJs: [],
    editMode: true, // 初始为编辑模式
    addComponent: (component: ComponentNode, parentId: number) => {
      set((state) => {
        // 防御性编程：深拷贝原始数据
        const newComponents = produce(state.components, (draft) => {
          // 添加查找失败处理
          const parentComponent = findComponentById(parentId, draft);
          if (!parentComponent) {
            console.error(`Parent component ${parentId} not found!`);
            return draft; // 重要：返回原数据避免空指针
          }

          component.parentId = parentId;

          // 安全的子元素初始化
          if (!parentComponent.children) {
            parentComponent.children = [];
          }

          // 检查重复添加
          const exists = parentComponent.children.some(
            (c) => c.id === component.id
          );
          if (!exists) {
            parentComponent.children.push(component);
          }
        });

        return { ...state, components: newComponents };
      });
    },
    updateComponent: (
      component: ComponentNode,
      id: number,
      position: Position
    ) => {
      set((state) => {
        const newComponents = produce(state.components, (draft) => {
          const targetComponent = findComponentById(id, draft);
          const parentComponent = findComponentById(
            targetComponent?.parentId!,
            draft
          );

          if (!parentComponent || !targetComponent) return;

          component.parentId = parentComponent.id;
          const targetIndex =
            parentComponent.children?.indexOf(targetComponent);

          if (targetIndex === undefined || targetIndex < 0) return;

          if (position === "before") {
            parentComponent.children?.splice(targetIndex, 0, component);
          } else {
            parentComponent.children?.splice(targetIndex + 1, 0, component);
          }
        });
        return { ...state, components: newComponents };
      });
    },
// store 中的 moveComponent 方法完整版
moveComponent: (id: number, targetId: number, position?: Position) => {
  set((state) => {
    const newComponents = produce(state.components, (draft) => {
      // 1. 查找源组件和目标组件
      const sourceComponent = findComponentById(id, draft);
      const targetComponent = findComponentById(targetId, draft);
      if (!sourceComponent || !targetComponent) return;

      // 2. 查找源组件的父组件
      const sourceParent = findComponentById(sourceComponent.parentId!, draft);
      if (!sourceParent || !sourceParent.children) return;

      // 3. 从原父节点移除（必须先移除再插入）
      const sourceIndex = sourceParent.children.findIndex((c) => c.id === id);
      if (sourceIndex === -1) return;
      const [movedNode] = sourceParent.children.splice(sourceIndex, 1);
      if (!movedNode) return;

      // 4. 判断插入类型
      if (position) {
        // 情况1: 插入到目标组件的兄弟位置（前/后）
        const targetParent = findComponentById(targetComponent.parentId!, draft);
        if (!targetParent || !targetParent.children) return;

        // 获取目标组件在父节点中的索引
        const targetIndex = targetParent.children.findIndex((c) => c.id === targetId);
        if (targetIndex === -1) return;

        // 更新父节点指向
        movedNode.parentId = targetParent.id; // ✅ 修复关键问题：更新父ID

        // 根据位置插入
        if (position === "before") {
          targetParent.children.splice(targetIndex, 0, movedNode);
        } else {
          targetParent.children.splice(targetIndex + 1, 0, movedNode);
        }
      } else {
        // 情况2: 插入到目标组件内部
        // 检查循环引用（禁止将父节点拖入自身子节点）
        let current: ComponentNode | undefined = targetComponent;
        while (current) {
          if (current.id === movedNode.id) {
            console.error("Cannot move component into its own children!");
            return;
          }
          current = findComponentById(current.parentId!, draft)!;
        }

        // 更新父节点指向
        movedNode.parentId = targetComponent.id; // ✅ 关键修复

        // 初始化子节点数组
        if (!targetComponent.children) {
          targetComponent.children = [];
        }

        // 插入到末尾
        targetComponent.children.push(movedNode);
      }
    });

    return { ...state, components: newComponents };
  });
},

    removeComponent(id) {
      set((state) => {
        const newComponents = produce(get().components, (draft) => {
          const component = findComponentById(id, draft);
          if (component) {
            const parentComponent = findComponentById(
              component.parentId!,
              draft
            );
            if (parentComponent) {
              parentComponent.children = parentComponent.children?.filter(
                (item) => item.id !== id
              );
            }
          }
        });
        return { ...state, components: newComponents };
      });
    },
    setCurComponent(id) {
      set((state) => {
        if (id === null) {
          return { ...state, currentElement: null, currentId: null };
        }
        const component = findComponentById(id, get().components);
        return { ...state, currentElement: component, currentId: id };
      });
    },
    setCurComponentProps(props) {
      set((state) => {
        if (!state.currentElement) return { ...state };
        const newComponent = produce(state.components, (draft) => {
          const component = findComponentById(state.currentElement!.id!, draft);
          if (component) {
            component.props = props;
          }
        });
        return { ...state, components: newComponent };
      });
    },
    resetComponents() {
      set({
        components: [
          {
            id: 1,
            name: "Page",
            desc: "页面",
            props: {},
            children: [],
          },
        ],
        currentElement: null,
        currentId: null,
      });
    },
    setPageJs(js) {
      set({ pageJs: js });
    },
    addPageJs(js) {
      set((state) => {
        return { ...state, pageJs: [...state.pageJs, js] };
      });
    },
    setBindEvents(id, events) {
      set((state) => {
        // 设置和更新组件绑定的事件
        const newComponents = produce(state.components, (draft) => {
          const component = findComponentById(id, draft);
          if (component) {
            if (component.bindEvents && component.bindEvents.length > 0)
              if (Array.isArray(events)) {
                component.bindEvents = events;
              } else {
                component.bindEvents.push(events);
              }
            else component.bindEvents = [events];
          }
        });
        // 更新当前选中的组件
        return {
          ...state,
          components: newComponents,
          currentElement: findComponentById(id, newComponents),
        };
      });
    },
    setEditMode(mode) {
      set({ editMode: mode });
    },
  })
);

/**
 *  根据id查找组件
 * @param id 组件id
 * @param components 组件树
 * @returns 组件
 */

export function findComponentById(
  id: number,
  components: ComponentNode[]
): ComponentNode | null {
  if (!id) return null;
  for (const component of components) {
    if (component.id === id) {
      return component;
    }
    if (component.children && component.children.length > 0) {
      const result = findComponentById(id, component.children);
      if (result !== null) return result;
    }
  }
  return null;
}

export default useComponentStore;
